//============================================================================
// Name        : Test.cpp
// Author      : Anthea Neums, Jonas Halbach
//			   :
// Description : Tests the functionality of the FileReader and PatternGenomAnalyser
//============================================================================

#include "Test.h"

#define THREAD_COUNT 4

using namespace std;

void testFileLoading()
{
	cout << "Start FileReader-Test" << endl;
	testFileLoadingError();
	testFileLoadingWorks();
	cout << "End FileReader-Test" << endl << endl;
}

void testFileLoadingError()
{
	char *filename = (char *) "not_availible.txt";

	FileReader *reader = new FileReader(filename);

	expectThat("Loading shall fail, so size of the stream should be 0!", 0, reader->getSize());

	delete reader;
	delete filename;
}

void testFileLoadingWorks()
{
	FileReader *testreader = new FileReader((char *)"txt/testfiles/AAAAAAAAAAAAAAAA.txt");
	char *testcontent = testreader->getContent();
	char testExpected[] = "AAAAAAAAAAAAAAAA";

	expectThat("The content of the test-file does not fit to the expected content", 1, strcmp(testExpected, testcontent) == 0);

	delete testreader;

}

void testPatternMatching()
{

	cout << "Start PatternGenomAnalyser-Test" << endl;
	testNoMatch();
	testOneMatch();
	cout << "End PatternGenomAnalyser-Test" << endl;

}

void testNoMatch()
{
	char *genomSource = (char *)"txt/testfiles/A_Genom.txt";
	char *patternSource = (char *) "txt/testfiles/A_Pattern.txt";

	FileReader *genomreader = new FileReader(genomSource);
	FileReader *patternreader = new FileReader(patternSource);

	algorithm::ThreadingPatternGenomAnalyser *analyser = new algorithm::ThreadingPatternGenomAnalyser(patternSource, genomSource, 16, THREAD_COUNT);

	cout << "specified wordlength : 16" << endl;

	cout << "Genom-content : " << genomreader->getContent() << endl;
	cout << "Pattern-content : " << patternreader->getContent() << endl;

	list<algorithm::Found *> *expectedList = new list<algorithm::Found *>();

	analyser->findSimilarStrings();

	list<algorithm::Found *> *founds = analyser->getFounds();

	expectThat("Lists shall both be empty!", 1, *expectedList == *founds);

	cout << endl;

	delete genomreader;
	delete patternreader;
	//delete genomSource;
	//delete patternSource;
	delete analyser;
}

void testOneMatch()
{

	char *source = (char *)"txt/testfiles/AAAAAAAAAAAAAAAA.txt";

	FileReader *genomreader = new FileReader(source);
	FileReader *patternreader = new FileReader(source);

	char *result = genomreader->getContent();

	algorithm::ThreadingPatternGenomAnalyser *analyser = new algorithm::ThreadingPatternGenomAnalyser(source, source, 16, THREAD_COUNT);

	cout << "specified wordlength : 16" << endl;

	cout << "Genom-content : " << result << endl;
	cout << "Pattern-content : " << result << endl;

	list<algorithm::Found *> *expectedList = new list<algorithm::Found *>();
	algorithm::Found *found = new algorithm::Found(0, 0,16, result);
	expectedList->push_back(found);

	analyser->findSimilarStrings();

	list<algorithm::Found *> *founds = analyser->getFounds();

	expectThat("Lists shall have one entry!", 1, expectedList->size() == founds->size());

	delete genomreader;
	delete patternreader;
	//delete source;
	delete analyser;
	delete result;
}

void testMultipleMatch()
{

	char *patternSource = (char *)"txt/testfiles/AAAAAAAAAAAAAAAAB_Pattern.txt";
	char *genomSource = (char *)"txt/testfiles/AAAAAAAAAAAAAAAAAB_Genom.txt";

	FileReader *genomreader = new FileReader(genomSource);
	FileReader *patternreader = new FileReader(patternSource);

	algorithm::ThreadingPatternGenomAnalyser *analyser = new algorithm::ThreadingPatternGenomAnalyser(patternSource, genomSource, 16, THREAD_COUNT);

	cout << "specified wordlength : 16" << endl;

	cout << "Genom-content : " << genomreader->getContent() << endl;
	cout << "Pattern-content : " << patternreader->getContent() << endl;

	list<algorithm::Found *> *expectedList = new list<algorithm::Found *>();

	char *patternpart1 = (char *) "AAAAAAAAAAAAAAAA";
	char *patternpart2 = (char *) "AAAAAAAAAAAAAAAAB";
	algorithm::Found *found = new algorithm::Found(0, 0, 16, patternpart1);
	algorithm::Found *found1 = new algorithm::Found(0, 0, 16, patternpart2);
	expectedList->push_back(found);
	expectedList->push_back(found);
	expectedList->push_back(found1);

	analyser->findSimilarStrings();

	list<algorithm::Found *> *founds = analyser->getFounds();

	expectThat("Matches shall be the same!", 1, expectedList->size() == founds->size());

	list<algorithm::Found *>::iterator it_expected = expectedList->begin();
	list<algorithm::Found *>::iterator it_found = founds->begin();

	while (it_expected != expectedList->end() && it_found != founds->end()) {

		expectThat("Content of list items shall be the same!", 1, strcmp((*it_expected)->getString(), (*it_found)->getString()) == 0);

		it_expected++;
		it_found++;
	}

	delete genomreader;
	delete patternreader;
	delete analyser;
	//delete patternpart1;
	//delete patternpart2;
	delete found;
	delete found1;
	delete expectedList;
}

/*
 * ATTENTION: First change the const-member wordlength of PatternGenomAnalyser-class to a smaller value like 3 for example.
 * This Method uses the PatternGenomAnalyser-class to match strings between a example-pattern and a example-genom.
 */
void showTestGenom()
{
	char *testPattern = (char *)"txt/testfiles/Pattern_short.txt";
	char *testGenom = (char *)"txt/testfiles/GenomProbe_short.txt";

	algorithm::ThreadingPatternGenomAnalyser *patternGenomAnalyser = new algorithm::ThreadingPatternGenomAnalyser(testPattern, testGenom, 3, THREAD_COUNT);

	patternGenomAnalyser->findSimilarStrings();

	patternGenomAnalyser->printFounds();


	//delete testPattern;
	//delete testGenom;
	delete patternGenomAnalyser;
}
